package org.hadoop.inverse;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import java.io.IOException;
public class InverseMR1 extends Configured implements Tool {
    @Override
    public int run(String[] args) throws Exception {
        Configuration conf = getConf();
        FileSystem fs = FileSystem.get(conf);
        Path dest = new Path("D:/a/out002");
        if (fs.exists(dest)) {
            fs.delete(dest, true);
        }
        Job job = Job.getInstance(conf, "InverseIndex");
        job.setJarByClass(getClass());
        job.setMapperClass(IIMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);
        job.setReducerClass(IIReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(NullWritable.class);
        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);
        FileInputFormat.setInputPaths(job, new Path("D:/a/in"));
        FileOutputFormat.setOutputPath(job, dest);
        int code = job.waitForCompletion(true) ? 0 : 1;
        return code;
    }
    public static class IIMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
        private String fileName = "";
        private Text key = new Text();
        private LongWritable value = new LongWritable(0L);
        @Override
        public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String[] strs = value.toString().split("\\s+");
            for (String str : strs) {
                this.key.set(str + "\t" + fileName);
                this.value.set(1L);
                context.write(this.key, this.value);
            }
        }
        @Override
        protected void setup(Context context) throws IOException, InterruptedException {
            InputSplit split = context.getInputSplit();
            if (split instanceof FileSplit) {
                FileSplit fileSplit = (FileSplit) split;
                fileName = fileSplit.getPath().getName();
            }
        }
    }
    public static class IIReducer extends Reducer<Text, LongWritable, Text, NullWritable> {
        @Override
        public void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
            long sum = 0L;
            for (LongWritable l : values) {
                sum += l.get();
            }
            key.set(key.toString() + "\t" + sum);
            context.write(key, NullWritable.get());
        }
    }
    public static void main(String[] args) throws Exception {
        int code = ToolRunner.run(new InverseMR1(), args);
        System.exit(code);
    }
}
